package cc.vv.party.api;


import cc.vv.party.beans.model.*
import cc.vv.party.beans.vo.OrgVO
import cc.vv.party.beans.vo.PartyReportVO

import cc.vv.party.common.base.BaseController;
import cc.vv.party.common.constants.StatusCode
import cc.vv.party.common.constants.SysConsts
import cc.vv.party.common.constants.enums.RoleType
import cc.vv.party.common.constants.enums.TerminalType
import cc.vv.party.common.wrapper.PageWrapper
import cc.vv.party.common.wrapper.ResponseEntityWrapper
import cc.vv.party.exception.BizException
import cc.vv.party.logger.annotation.OperateLog
import cc.vv.party.param.CommittedEditParam
import cc.vv.party.param.JobHuntingUserEditParam
import cc.vv.party.param.PartyReportEditParam
import cc.vv.party.param.PartyReportListParam
import cc.vv.party.service.CommittedService
import cc.vv.party.service.PartyReportService
import cc.vv.party.service.UserService
import cn.hutool.system.UserInfo
import com.baomidou.mybatisplus.mapper.EntityWrapper
import commonx.core.content.isNotNullOrEmpty
import commonx.core.content.transfer
import io.swagger.annotations.Api
import io.swagger.annotations.ApiImplicitParam
import io.swagger.annotations.ApiImplicitParams
import io.swagger.annotations.ApiOperation
import org.apache.commons.collections.CollectionUtils
import org.apache.commons.lang.StringUtils
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.session.jdbc.JdbcOperationsSessionRepository
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.bind.annotation.*
import java.util.*
import javax.validation.constraints.Pattern
import kotlin.streams.toList

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Gyb
 * @since 2018-10-12
 */
@RestController
@RequestMapping("/api/user")
@Api(value = "用户", tags = ["用户客户端API"], description = "用户客户端API-客户端用户相关接口")
class UserApi : BaseController() {

    @Autowired
    lateinit var userService: UserService

    @Autowired
    lateinit var partyReportService: PartyReportService

    @Autowired
    lateinit var repository: JdbcOperationsSessionRepository

    @Autowired
    lateinit var committedService: CommittedService

    @OperateLog("登录系统")
    @ApiOperation("客户端用户登录")
    @ApiImplicitParams(
        value = [
            ApiImplicitParam(value = "账号", name = "account"),
            ApiImplicitParam(value = "密码", name = "password")
        ]
    )
    @PostMapping("/login")
    fun userLogin(
        @Pattern(
            regexp = SysConsts.REGEX_MOBILE,
            message = "账号格式不正确"
        ) @RequestParam account: String, @RequestParam password: String
    ): ResponseEntityWrapper<MutableMap<String, Any?>> {
        val result = userService.appUserLogin(account, password)
        val session = getSessionIfAbsent()
        result["token"] = session.id
        session.setAttribute(SysConsts.SESSION_KEY_USER_INFO, result)
        session.setAttribute(SysConsts.SESSION_KEY_USER_ID, result["userId"])
        session.setAttribute(SysConsts.SESSION_KEY_DEVICE, TerminalType.APP)
        session.setAttribute(SysConsts.SESSION_KEY_USER_NAME, result["userName"])
        session.setAttribute(SysConsts.SESSION_KEY_USER_ACCOUNT, result["userAccount"])
        session.setAttribute(SysConsts.SESSION_KEY_USER_ROLE, result["userRole"])
        session.setAttribute(SysConsts.SESSION_KEY_YANAN_ROLE_ID, result["yananRole"])
//        session.setAttribute(SysConsts.SESSION_KEY_USER_ORG, result["org"])
//        session.setAttribute(SysConsts.SESSION_KEY_USER_ORG_TREE, result["orgTree"])
//        session.setAttribute(SysConsts.SESSION_KEY_APP_USER_ORG, result["userOrgList"])
        session.setAttribute(SysConsts.SESSION_KEY_LOCAL_USER_INFO, result["reportedPartyMemberInfo"])
        session.setAttribute(SysConsts.SESSION_KEY_CURRENT_BRANCH, result["currentBranchInfo"])
        session.setAttribute(SysConsts.SESSION_KEY_MANAGE_ORG_INFO, result["userManageOrg"])
        session.setAttribute(SysConsts.SESSION_KEY_ADMIN_ORG, result["userOrgList"])

//        var loginController = LoginController()
//        loginController.account = account
//        loginController.token = session.id


//        val list = LoginController().selectList(EntityWrapper<LoginController>().where("account = {0}", account))
//        if (CollectionUtils.isNotEmpty(list)) {
//            var tokenList = list.stream().map { it.token }.toList()
//            for (token in tokenList) {
//                repository.deleteById(token)
//            }
//            LoginController().delete(EntityWrapper<LoginController>().`in`("token", tokenList))
//        }
//
//        loginController.insert()
        return success(result)
    }

    @OperateLog("注销系统")
    @ApiOperation("注销")
    @PostMapping("/logout")
    fun logout(): ResponseEntityWrapper<*> {
        val session = getSession()
        session.invalidate()
        repository.deleteById(session.id)
//        LoginController().delete(EntityWrapper<LoginController>().where("token = {0}", session.id))
        return success(null)
    }

    @OperateLog("提交党员报道")
    @ApiOperation("提交党员报道")
    @PostMapping("/reported/submit")
    @Transactional
    fun userReport(@RequestBody reportParam: PartyReportEditParam): ResponseEntityWrapper<Any> {
        val report = reportParam.transfer<PartyReport>()
        report.id = getCurrentUserId()
        return if (partyReportService.insertOrUpdate(report)) {
            val user = userService.selectById(getCurrentUserId()) ?: User()
            user.id = getCurrentUserId()
            user.name = getCurrentUserName()
            user.reportTime = Date()
            user.reported = SysConsts.REPORTED
            user.street = reportParam.street
            user.community = reportParam.community
            user.grid = reportParam.grid
            user.party = Integer(0)
            userService.insertOrUpdate(user)
            val userVo = getCurrentUserInfo()
            userVo.street = user.street
            userVo.community = user.community
            userVo.grid = user.grid
            userVo.reported = user.reported.toString()
            userVo.reportTime = user.reportTime
            getSession().setAttribute(SysConsts.SESSION_KEY_LOCAL_USER_INFO, userVo)



            //添加党员承诺
            var committedEditParam = CommittedEditParam()
            committedEditParam.committedType = Integer(1)
            committedEditParam.targetId = user.id
            committedEditParam.content = reportParam.personalCommitment
            committedEditParam.completeTime = Date().time
            committedEditParam.mobile = reportParam.mobile
            committedService.edit(committedEditParam, user.id!!)


            //设置支部管理员权限
            val yananRole = getSession().getAttribute(SysConsts.SESSION_KEY_YANAN_ROLE_ID)
            if(yananRole != null && "RPOME".equals(yananRole.toString(), true)){
                val role = Role().selectOne(EntityWrapper<Role>().where("type = {0}", "branch"))
                var userRole = UserRole()
                userRole.userAccount = getCurrentUserAccount()
                userRole.roleId = role.id
                userRole.createUser = userVo.id
                userRole.insert()
            }

            success(null)
        } else {
            error(StatusCode.ERROR.statusCode, "报道失败")
        }
    }

    @OperateLog("查看党员报道详情")
    @ApiOperation("党员报道详情")
    @GetMapping("/reported/detail")
    fun userReportDetail(): ResponseEntityWrapper<PartyReportVO> {
        return success(partyReportService.selectById(getCurrentUserId()).transfer<PartyReportVO>())
    }


    @OperateLog(content = "查看党员报道信息列表")
    @ApiOperation(value = "获取党员报道信息列表", notes = "获取党员报道信息列表")
    @ApiImplicitParams(
        value = [
            (ApiImplicitParam(name = "size", value = "每页显示数量", required = true)),
            (ApiImplicitParam(name = "page", value = "页码", required = true))
        ]
    )
    @PostMapping(value = "/list/{page}/{size}")
    fun listPage(
        @RequestBody param: PartyReportListParam,
        @PathVariable size: Int,
        @PathVariable page: Int
    ): ResponseEntityWrapper<PageWrapper<PartyReportVO>> {
        var roleList = getCurrentUserRole()
        if (roleList.size == 1 && roleList[0].type == RoleType.PARTY_MEMBER) throw BizException(StatusCode.FORBIDDEN)
        return success(partyReportService.selectReportUserList(param, size, page))
    }
}
